package com.niiwoo.civet.mobile.controller.creditor;

import com.alibaba.dubbo.config.annotation.Reference;
import com.niiwoo.civet.mobile.vo.common.ConfigArea;
import com.niiwoo.civet.mobile.vo.common.ConfigItem;
import com.niiwoo.civet.mobile.vo.request.creditor.TradableInvestOrderFilterRequestVO;
import com.niiwoo.civet.mobile.vo.response.creditor.*;
import com.niiwoo.civet.mobile.vo.response.creditor.TradableInvestOrderConfigResponseVO.RelationConfig;
import com.niiwoo.civet.trade.dto.common.SimpleNotifyDTO;
import com.niiwoo.civet.trade.dto.request.creditor.TradableInvestOrderFilterRequestDTO;
import com.niiwoo.civet.trade.dto.response.RelationInvestStdConfigDTO;
import com.niiwoo.civet.trade.dto.response.RelationInvestStdConfigItemDTO;
import com.niiwoo.civet.trade.dto.response.creditor.CreditorConfigDTO;
import com.niiwoo.civet.trade.dto.response.creditor.CreditorQueryConditionDTO;
import com.niiwoo.civet.trade.dto.response.intelligenceInvest.IntelligenceInvestSwitchResponseDTO;
import com.niiwoo.civet.trade.dto.response.intelligenceInvest.IsSmartInvestSoldOutResponseDTO;
import com.niiwoo.civet.trade.enums.Intelligence.IntelligenceSwitchSourceEnum;
import com.niiwoo.civet.trade.enums.InvestStdProductTypeEnum;
import com.niiwoo.civet.trade.service.creditor.CreditorConfigDubboService;
import com.niiwoo.civet.trade.service.intelligenceInvest.IntelligenceInvestDubboService;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.web.annotation.AuthIgnore;
import com.niiwoo.tripod.web.util.PrincipalContext;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/creditorConfig")
@Api(tags = "V5.4.0--债权配置", description = "/creditorConfig")
public class CreditorConfigController {
	
	@Reference(version = "1.0.0")
    private CreditorConfigDubboService creditorConfigDubboService;

	@Reference(version = "1.0.0")
	private IntelligenceInvestDubboService intelligenceInvestDubboService;
	
	private static final String NOTIFY_SEQ = "\\|";
	
	@AuthIgnore
	@PostMapping("/switch")
    @ApiOperation("V5.3.0--债权转让开关")
    public Result<CreditorSwitchResponseVO> creditorSwitch() {
		CreditorSwitchResponseVO result = new CreditorSwitchResponseVO();
		
		CreditorConfigDTO notifyDTO = creditorConfigDubboService.getCreditorConfigs();
		if (notifyDTO != null) {
			result.setCreditorSwitch(notifyDTO.getCreditorSwitch());
			result.setCreditorSubmitSwitch(notifyDTO.getCreditorSubmitSwitch());
		}

		IntelligenceInvestSwitchResponseDTO responseDTO = intelligenceInvestDubboService.intelligenceInvestSwitch(IntelligenceSwitchSourceEnum.NORMAL.getCode());
		if (responseDTO != null) {
			result.setIntelligenceInvestSwitch(responseDTO.getIntelligenceInvestSwitch().intValue());
		}
		IsSmartInvestSoldOutResponseDTO outResponseDTO = intelligenceInvestDubboService.queryIntelligenceInvestCount(PrincipalContext.getUserId());
		result.setIsSmartInvestSoldOut(outResponseDTO.getIsSmartInvestSoldOut());
		result.setIsProjectInvestSoldOut(outResponseDTO.getIsProjectInvestSoldOut());
		return Result.with(result);
    }
	
	@AuthIgnore
	@PostMapping("/limit")
    @ApiOperation("V5.3.0--债权转让限制")
    public Result<CreditorLimitResponseVO> creditorLimit() {
		CreditorLimitResponseVO result = new CreditorLimitResponseVO();
		result.setIsShowApplyTime(0); //默认不显示申请债权转让时间范围
		
		CreditorConfigDTO notifyDTO = creditorConfigDubboService.getCreditorConfigs();
		if (notifyDTO != null) {
			result.setApplyTimeBegin(notifyDTO.getApplyTimeBegin());
			result.setApplyTimeEnd(notifyDTO.getApplyTimeEnd());
			
			// 是否开启时间内
			DateTime currentDate = new DateTime();
			String startTime = notifyDTO.getApplyTimeBegin();
			String endTime = notifyDTO.getApplyTimeEnd();
			
			if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
				throw new BizException("TRD1000007"); //配置不存在
			}
			
			DateTime dateTimeStart = new DateTime(currentDate.getYear(), currentDate.getMonthOfYear(), currentDate.getDayOfMonth(), Integer.parseInt(startTime.split(":")[0]),
					Integer.parseInt(startTime.split(":")[1]), 0);
			DateTime dateTimeEnd = new DateTime(currentDate.getYear(), currentDate.getMonthOfYear(),
					currentDate.getDayOfMonth(), Integer.parseInt(endTime.split(":")[0]), Integer.parseInt(endTime.split(":")[1]), 0);
	        if (currentDate.getMillis() < dateTimeStart.getMillis() || currentDate.getMillis() > dateTimeEnd.getMillis()){
	        	result.setIsShowApplyTime(1);
	        }
		}
		
		return Result.with(result);
    }
	
	@AuthIgnore
	@PostMapping("/condition/notify")
    @ApiOperation("V5.3.0--债权转让条件提示框")
    public Result<CreditorNotifyResponseVO> getTradableInvestOrderConditionNotify() {
		CreditorNotifyResponseVO result = new CreditorNotifyResponseVO();
		
		SimpleNotifyDTO notifyDTO = creditorConfigDubboService.getTradableInvestOrderConditionNotify();
		if (notifyDTO != null && !StringUtils.isEmpty(notifyDTO.getContent())) {
			List<String> contents = new ArrayList<>();
			
			String content = notifyDTO.getContent().replaceAll("\n", "").replaceAll("\r", "");
			List<String> list = Arrays.asList(content.split(NOTIFY_SEQ));
			for (String s : list) {
				contents.add(s);
			}
			
			result.setContents(contents);
		}
		
		return Result.with(result);
    }
	
	@AuthIgnore
	@PostMapping("/rate/notify")
    @ApiOperation("V5.3.0--债权费率提示框")
    public Result<CreditorNotifyResponseVO> getTradableInvestOrderRateNotify() {
		CreditorNotifyResponseVO result = new CreditorNotifyResponseVO();
		
		SimpleNotifyDTO notifyDTO = creditorConfigDubboService.getTradableInvestOrderRateNotify();
		
		if (notifyDTO != null && !StringUtils.isEmpty(notifyDTO.getContent())) {
			List<String> contents = new ArrayList<>();
			
			String content = notifyDTO.getContent().replaceAll("\n", "").replaceAll("\r", "");
			List<String> list = Arrays.asList(content.split(NOTIFY_SEQ));
			for (String s : list) {
				contents.add(s);
			}
			result.setContents(contents);
		}
		return Result.with(result);
    }
	
	@AuthIgnore
	@PostMapping("/tradable/all")
    @ApiOperation("V5.4.0--可转让债权配置")
    public Result<TradableInvestOrderConfigResponseVO> getTradableInvestOrderCondition() {
		String userId = PrincipalContext.getUserId();
		
		TradableInvestOrderConfigResponseVO result = new TradableInvestOrderConfigResponseVO();
		
		CreditorQueryConditionDTO dto = creditorConfigDubboService.getCreditorQueryCondition(userId);
		
		if (dto == null || dto.getRelations() == null || dto.getRelations().isEmpty()) return Result.with(new TradableInvestOrderConfigResponseVO()); 
		
		RelationConfig rConfig = null;
		List<RelationConfig> rConfigs = new ArrayList<>();
		ConfigArea configArea = null;
		List<RelationInvestStdConfigItemDTO> items = null;
		for (RelationInvestStdConfigDTO config : dto.getRelations()) { 
			rConfig = new RelationConfig();
			
			items = config.getItems();
			for (RelationInvestStdConfigItemDTO item : items) {
				switch (item.getConfigType()) { //参见 InvestStdConfigTypeEnum
				case 1: //标的类型
					rConfig.setProductType(new ConfigItem(item.getId(), String.valueOf(item.getByteVal()), item.getTitle()));
					break;
				case 2: //剩余期限
					configArea = new ConfigArea();
					configArea.setConfigId(item.getId());
					configArea.setTitle(item.getTitle());
					configArea.setBegin(String.valueOf(item.getMinval().intValue()));
					configArea.setBeginQueryType(item.getMinvalCalSymbol());
					configArea.setEnd(String.valueOf(item.getMaxval().intValue()));
					configArea.setEndQueryType(item.getMaxvalCalSymbol());
					rConfig.setRestPeriod(configArea);
					break;
				case 3: //还款方式
					rConfig.setRepaymentType(new ConfigItem(item.getId(), String.valueOf(item.getByteVal()), item.getTitle()));
					break;
				case 4: //利率
					if (item.getMinval().compareTo(new BigDecimal(1)) > 0) {
						item.setMinval(item.getMinval().divide(new BigDecimal(100)));
					}
					
					rConfig.setInterestReate(new ConfigItem(item.getId(), String.valueOf(item.getMinval()), item.getTitle()));
					break;
				case 5: //可投金额
					break;
				}
			}
			
			rConfigs.add(rConfig);
		}
		
		result.setRelations(rConfigs);
		
		return Result.with(result);
    }
	
	@AuthIgnore
	@PostMapping("/tradable/relation")
    @ApiOperation("V5.4.0--级联方式获取筛选条件")
    public Result<TradableInvestOrderRelationConfigResponseVO> getTradableInvestOrderRelationConfig(@RequestBody @Valid TradableInvestOrderFilterRequestVO request) {
		TradableInvestOrderRelationConfigResponseVO result = new TradableInvestOrderRelationConfigResponseVO();
		
		TradableInvestOrderFilterRequestDTO requestDTO = new TradableInvestOrderFilterRequestDTO();
		requestDTO.setConfigType(request.getConfigType() == 0 || request.getConfigType() == 0 ? null : request.getConfigType());
		requestDTO.setLoanTypeConfigId(request.getLoanTypeConfigId());
		requestDTO.setPeriodConfigId(request.getRestPeriodConfigId());
		requestDTO.setRepaymentTypeConfigId(request.getRepaymentTypeConfigId());
		requestDTO.setInterestRateConfigId(request.getInterestRateConfigId());
		requestDTO.setProductType(InvestStdProductTypeEnum.INITIATE_TRANSFER.getValue());
		
		List<RelationInvestStdConfigItemDTO> list = creditorConfigDubboService.getCreditorRelationQueryCondition(requestDTO);
		
		if (list == null || list.isEmpty()) return Result.with(new TradableInvestOrderRelationConfigResponseVO()); 
		
		ConfigArea configArea = null;
		
		List<ConfigItem> productType = new ArrayList<>();
		List<ConfigArea> restPeriod = new ArrayList<>();
		List<ConfigItem> repaymentType = new ArrayList<>();
		List<ConfigItem> interestReate = new ArrayList<>();
		for (RelationInvestStdConfigItemDTO item : list) {
			switch (item.getConfigType()) { //参见 InvestStdConfigTypeEnum
			case 1: //标的类型
				productType.add(new ConfigItem(item.getId(), String.valueOf(item.getByteVal()), item.getTitle()));
				break;
			case 2: //剩余期限
				configArea = new ConfigArea();
				configArea.setConfigId(item.getId());
				configArea.setTitle(item.getTitle());
				configArea.setBegin(String.valueOf(item.getMinval().intValue()));
				configArea.setBeginQueryType(item.getMinvalCalSymbol());
				configArea.setEnd(String.valueOf(item.getMaxval().intValue()));
				configArea.setEndQueryType(item.getMaxvalCalSymbol());
				restPeriod.add(configArea);
				break;
			case 3: //还款方式
				repaymentType.add(new ConfigItem(item.getId(), String.valueOf(item.getByteVal()), item.getTitle()));
				break;
			case 4: //利率
				if (item.getMinval().compareTo(new BigDecimal(1)) > 0) {
					item.setMinval(item.getMinval().divide(new BigDecimal(100)));
				}
				
				interestReate.add(new ConfigItem(item.getId(), String.valueOf(item.getMinval()), item.getTitle()));
				break;
			case 5: //可投金额
				break;
			}
		}
		
		result.setInterestReate(interestReate);
		result.setProductType(productType);
		result.setRepaymentType(repaymentType);
		result.setRestPeriod(restPeriod);
		
		return Result.with(result);
    }
}
